const isArray = (a) => {
	return Array.isArray(a);
}
import {
	exportDefault,
	titleCase,
	deepClone
} from '@/utils/index'
import ruleTrigger from './ruleTrigger'

const units = {
	KB: '1024',
	MB: '1024 / 1024',
	GB: '1024 / 1024 / 1024'
}
let confGlobal
const inheritAttrs = {
	file: '',
	dialog: 'inheritAttrs: false,'
}
const imports={}
/**
 * 组装js 【入口函数】
 * @param {Object} formConfig 整个表单配置
 * @param {String} type 生成类型，文件或弹窗等
 */
export function makeUpJs(formConfig, type) {

	confGlobal = formConfig = deepClone(formConfig)
	const dataList = []
	const ruleList = []
	const optionsList = []
	const propsList = []
	const methodList = mixinMethod(type)
	const uploadVarList = []
	const created = []

	formConfig.fields.forEach(el => {
		buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList, created)
	})

	const script = buildexport(
		formConfig,
		type,
		dataList.join('\n'),
		ruleList.join('\n'),
		optionsList.join('\n'),
		uploadVarList.join('\n'),
		propsList.join('\n'),
		methodList.join('\n'),
		created.join('\n')
	)
	confGlobal = null
		console.log(imports)
	let import_script=Object.values(imports).join('\n');

	return import_script+"\n"+script;
}

// 构建组件属性
function buildAttributes(scheme, dataList, ruleList, optionsList, methodList, propsList, uploadVarList, created) {
	const config = scheme.__config__
	const slot = scheme.__slot__
	buildData(scheme, dataList)
	buildRules(scheme, ruleList)

	// 特殊处理options属性
	if (scheme.options || (slot && slot.options && slot.options.length)) {
		buildOptions(scheme, optionsList)
		if (config.dataType === 'dynamic') {
			const model = `${scheme.__vModel__}Options`
			const options = titleCase(model)
			const methodName = `get${options}`
			buildOptionMethod(methodName, model, methodList, scheme)
			callInCreated(methodName, created)
		}
	}

	// 处理props
	if (scheme.props && scheme.props.props) {
		buildProps(scheme, propsList)
	}

	// 处理el-upload的action
	if (scheme.action && config.tag === 'el-upload') {
		uploadVarList.push(
			`${scheme.__vModel__}Action: '${scheme.action}',
      ${scheme.__vModel__}fileList: [],`
		)
		methodList.push(buildBeforeUpload(scheme))
		// 非自动上传时，生成手动上传的函数
		if (!scheme['auto-upload']) {
			methodList.push(buildSubmitUpload(scheme))
		}
	}

	// 构建子级组件属性
	if (config.children) {
		config.children.forEach(item => {
			buildAttributes(item, dataList, ruleList, optionsList, methodList, propsList, uploadVarList,
				created)
		})
	}
}

// 在Created调用函数
function callInCreated(methodName, created) {
	created.push(`this.${methodName}()`)
}

// 混入处理函数
function mixinMethod(type) {
	const list = [];
	const
		minxins = {
			file: confGlobal.formBtns ? {
				submitForm: `submitForm() {
        this.$refs['${confGlobal.formRef}'].validate(valid => {
          if(!valid) return
          // TODO 提交表单
        })
      },`,
				resetForm: `resetForm() {
        this.$refs['${confGlobal.formRef}'].resetFields()
      },`
			} : null,
			dialog: {
				onOpen: 'onOpen() {},',
				onClose: `onClose() {
        this.$refs['${confGlobal.formRef}'].resetFields()
      },`,
				close: `close() {
        this.$emit('update:visible', false)
      },`,
				handelConfirm: `handelConfirm() {
        this.$refs['${confGlobal.formRef}'].validate(valid => {
          if(!valid) return
          this.close()
        })
      },`
			}
		}

	const methods = minxins[type]
	if (methods) {
		Object.keys(methods).forEach(key => {
			list.push(methods[key])
		})
	}

	return list
}

// 构建data
function buildData(scheme, dataList) {
	const config = scheme.__config__
	if (scheme.__vModel__ === undefined) return
	const defaultValue = JSON.stringify(config.defaultValue)
	dataList.push(`${scheme.__vModel__}: ${defaultValue},`)
}

// 构建校验规则
function buildRules(scheme, ruleList) {
	const config = scheme.__config__
	if (scheme.__vModel__ === undefined) return
	const rules = []
	if (ruleTrigger[config.tag]) {
		if (config.required) {
			const type = isArray(config.defaultValue) ? 'type: \'array\',' : ''
			let message = isArray(config.defaultValue) ? `请至少选择一个${config.label}` : scheme.placeholder
			if (message === undefined) message = `${config.label}不能为空`
			rules.push(`{ required: true, ${type} message: '${message}', trigger: '${ruleTrigger[config.tag]}' }`)
		}
		if (config.regList && isArray(config.regList)) {
			config.regList.forEach(item => {
				if (item.pattern) {
					rules.push(
						`{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${ruleTrigger[config.tag]}' }`
					)
				}
			})
		}
		ruleList.push(`${scheme.__vModel__}: [${rules.join(',')}],`)
	}
}

// 构建options
function buildOptions(scheme, optionsList) {
	if (scheme.__vModel__ === undefined) return
	// el-cascader直接有options属性，其他组件都是定义在slot中，所以有两处判断
	let {
		options
	} = scheme
	if (!options) options = scheme.__slot__.options
	if (scheme.__config__.dataType === 'dynamic') {
		options = []
	}
	const str = `${scheme.__vModel__}Options: ${JSON.stringify(options)},`
	optionsList.push(str)
}

function buildProps(scheme, propsList) {
	const str = `${scheme.__vModel__}Props: ${JSON.stringify(scheme.props.props)},`
	propsList.push(str)
}

// el-upload的BeforeUpload
function buildBeforeUpload(scheme) {
	imports["ElMessage"]="import { ElMessage } from 'element-plus'";
	
	const config = scheme.__config__
	const unitNum = units[config.sizeUnit];
	let rightSizeCode = '';
	let acceptCode = '';
	const
		returnList = []
	if (config.fileSize) {
		rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${config.fileSize}
    if(!isRightSize){
      ElMessage.error('文件大小超过 ${config.fileSize}${config.sizeUnit}')
    }`
		returnList.push('isRightSize')
	}
	if (scheme.accept) {
		acceptCode = `let isAccept = new RegExp('${scheme.accept}').test(file.type)
    if(!isAccept){
      ElMessage.error('应该选择${scheme.accept}类型的文件')
    }`
		returnList.push('isAccept')
	}
	const str = `${scheme.__vModel__}BeforeUpload(file) {
    ${rightSizeCode}
    ${acceptCode}
    return ${returnList.join('&&')}
  },`
	return returnList.length ? str : ''
}

// el-upload的submit
function buildSubmitUpload(scheme) {
	const str = `submitUpload() {
    this.$refs['${scheme.__vModel__}'].submit()
  },`
	return str
}

function buildOptionMethod(methodName, model, methodList, scheme) {
	imports["axios"]="import  axios  from 'axios'";
	const config = scheme.__config__
	const str = `${methodName}() {
     
    axios({
      method: '${config.method}',
      url: '${config.url}'
    }).then(resp => {
      var { data } = resp
      this.${model} = data.${config.dataPath}
    })
  },`
	methodList.push(str)
}

// js整体拼接
function buildexport(conf, type, data, rules, selectOptions, uploadVar, props, methods, created) {
	const str = `${exportDefault}{
  ${inheritAttrs[type]}
  components: {},
  props: [],
  data () {
    return {
      ${conf.formModel}: {
        ${data}
      },
      ${conf.formRules}: {
        ${rules}
      },
      ${uploadVar}
      ${selectOptions}
      ${props}
    }
  },
  computed: {},
  watch: {},
  created () {
    ${created}
  },
  mounted () {},
  methods: {
    ${methods}
  }
}`
	return str
}
